package com.block.chlunion.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.block.chlunion.enums.UnionActionEnum;
import com.block.chlunion.enums.UnionStatusEnum;
import com.block.chlunion.model.UnionLoginDTO;
import com.block.chlunion.model.param.UnionCheckParam;
import com.block.chlunion.model.param.UnionLoginParam;
import com.block.chlunion.service.IChannelUnionResultInfoService;
import com.block.chlunion.service.IChannelUnionService;
import com.block.chlunion.service.IChannleUnionAddupService;
import com.block.common.model.dto.CountInfoDTO;
import com.block.common.model.vo.CheckUserVO;
import com.block.common.model.vo.ResultInfoVO;
import com.block.common.service.IApplicationInfoService;
import com.block.common.service.ICountCommonService;
import com.block.common.service.IMemberCommonService;
import com.block.common.service.LogFactory;
import com.block.db.entity.ApplicationInfo;
import com.block.db.entity.ChannelInfo;
import com.block.db.entity.ChannelUnionResultInfo;
import com.block.db.entity.MemberInfo;
import com.block.db.mapper.ChannelUnionResultInfoMapper;
import com.block.db.mapper.MemberInfoMapper;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.Locale;

@Service
public class ChannelUnionServiceImpl implements IChannelUnionService {

    private static Logger log = LogFactory.getUnionLog();

    @Resource
    MemberInfoMapper memberInfoMapper;
    @Autowired
    IChannleUnionAddupService channleUnionAddupService;
    @Autowired
    IMemberCommonService memberCommonService;
    @Autowired
    IApplicationInfoService applicationInfoService;
    @Autowired
    IChannelUnionResultInfoService channelUnionResultInfoService;
    @Resource
    ChannelUnionResultInfoMapper channelUnionResultInfoMapper;
    @Autowired
    ICountCommonService countCommonService;

    @Override
    public ResultInfoVO checkUser(ChannelInfo channelInfo, UnionCheckParam unionCheckParam){

        String dateInfo = LocalDate.now().toString();
        channleUnionAddupService.saveOrUpdateDataAddupInfo(dateInfo, UnionActionEnum.CHECK, channelInfo);

        unionCheckParam.setMobileMd5(unionCheckParam.getMobileMd5().toLowerCase());
        unionCheckParam.setDateInfo(dateInfo);

        String mobileMd5 = unionCheckParam.getMobileMd5();

        CheckUserVO checkUserVO = new CheckUserVO();
        checkUserVO.setCanPush(false);
        checkUserVO.setMobileMd5(mobileMd5);
        ChannelUnionResultInfo resultInfo = channelUnionResultInfoService.saveResultInfo(channelInfo, unionCheckParam);
        if (ObjectUtil.isEmpty(resultInfo)){
            log.info("【联登撞库】保存撞库信息失败【channelCode】{}【unionCheckParam】{}", channelInfo.getChannelCode(), JSON.toJSONString(unionCheckParam));
            return ResultInfoVO.error("记录操作失败");
        }

        // 检测数据是否已经入库
        MemberInfo memberInfo = memberInfoMapper.getMemberInfoByMobileMd5(unionCheckParam.getMobileMd5());
        if (ObjectUtil.isNotEmpty(memberInfo)){
            log.info("【联登撞库】用户信息已存在【channelCode】{}【unionCheckParam】{}", channelInfo.getChannelCode(), JSON.toJSONString(unionCheckParam));
            return ResultInfoVO.success(checkUserVO.toJsonObject());
        }

        checkUserVO.setCanPush(true);
        checkUserVO.setTradeNo(String.valueOf(resultInfo.getId()));
        return ResultInfoVO.success(checkUserVO.toJsonObject());
    }

    @Override
    public ResultInfoVO unionLogin(ChannelInfo channelInfo, UnionLoginParam unionLoginParam) {
        /**
         * 返回用户登陆链接信息
         *
         */
        ChannelUnionResultInfo resultInfo = channelUnionResultInfoMapper.getEntityByTradeNoLock(unionLoginParam.getTradeNo());
        if (ObjectUtil.isEmpty(resultInfo)){
            log.info("【联登注册】交易订单为空【channelCode】{}【unionLoginParam】{}", channelInfo.getChannelCode(), JSON.toJSONString(unionLoginParam));
            return ResultInfoVO.error("联登失败");
        }
        String mobilemd5 = SecureUtil.md5(unionLoginParam.getMobile()).toLowerCase(Locale.ROOT);
        if (!StrUtil.equals(resultInfo.getMobileMd5(),mobilemd5 )){
            log.info("【联登注册】请求的手机号与库存手机号不一致【channelCode】{}【unionLoginParam】{}", channelInfo.getChannelCode(), JSON.toJSONString(unionLoginParam));
            return ResultInfoVO.error("联登手机号不一致");
        }

        String mobile = unionLoginParam.getMobile();

        UnionLoginDTO unionLoginDTO = new UnionLoginDTO();
        unionLoginDTO.setDateInfo(resultInfo.getDateInfo());
        unionLoginDTO.setResultInfoId(resultInfo.getId());

        // 查询用户是否存在
        MemberInfo memberInfo = memberInfoMapper.getBaseUserInfoByPhoneLock(mobile);
        if (ObjectUtil.isNotEmpty(memberInfo)){
            unionLoginDTO.setUnionStatusEnum(UnionStatusEnum.FAILED);
            unionLoginDTO.setResultMsg("用户手机号已经存在");
            channelUnionResultInfoService.updateResultInfo(channelInfo, unionLoginDTO);
            log.info("【联登注册】用户信心已存在【channelCode】{}【unionLoginParam】{}", channelInfo.getChannelCode(), JSON.toJSONString(unionLoginParam));
            return ResultInfoVO.error("用户信息已存在");
        }

        ApplicationInfo applicationInfo = applicationInfoService.getAppInfoByType(channelInfo.getAppType());
        // 注册用户信息
        memberInfo = memberCommonService.saveMemberInfo(mobile, channelInfo, applicationInfo, null, resultInfo.getReqIp(), null);
        if (ObjectUtil.isEmpty(memberInfo)){
            unionLoginDTO.setUnionStatusEnum(UnionStatusEnum.FAILED);
            unionLoginDTO.setResultMsg("新增用户信息失败");
            channelUnionResultInfoService.updateResultInfo(channelInfo, unionLoginDTO);
            log.info("【联登注册】新增用户信息失败【channelCode】{}【unionLoginParam】{}", channelInfo.getChannelCode(), JSON.toJSONString(unionLoginParam));
            return ResultInfoVO.error("联登失败，请重试");
        }

        // TODO: 2023/6/9 返回链接模板
        String loginUrl = StrUtil.format("{}/exp/chl/{}?u={}", applicationInfo.getExtUrl(), channelInfo.getChannelCode(), memberInfo.getUid());

        // 返回用户登陆链接等信息
        JSONObject returnData = new JSONObject();
        returnData.put("loginUrl", loginUrl);

        // 更新联登结果
        unionLoginDTO.setUid(memberInfo.getUid());
        unionLoginDTO.setUnionStatusEnum(UnionStatusEnum.SUCCESS);
        unionLoginDTO.setResultMsg(JSON.toJSONString(returnData));
        boolean result = channelUnionResultInfoService.updateResultInfo(channelInfo, unionLoginDTO);
        log.info("【联登成功】更新联登信息【unionLoginDTO】{}", JSON.toJSONString(unionLoginDTO));

        CountInfoDTO countInfoDTO = new CountInfoDTO();
        countInfoDTO.setChannelCode(channelInfo.getChannelCode());
        countInfoDTO.setRegisterCost(channelInfo.getChargeAmount());

        //渠道信息统计
        countCommonService.calculateDataInfo2(countInfoDTO);

        if (result){
            return ResultInfoVO.success(returnData);
        }else{
            return ResultInfoVO.error("操作失败");
        }
    }

}
